package com.dongdongshop.callback;

import com.dongdongshop.pojo.Goods;
import com.dongdongshop.service.GoodsService;
import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.messaging.Message;

import java.util.Locale;
import java.util.concurrent.TimeUnit;

@RocketMQTransactionListener
public class MQCallbackTransactionListener implements RocketMQLocalTransactionListener {
    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private GoodsService goodsService;

    /**
     * 1、MQ服务，成功接到事物消息后，执行本方法；
     * 2、处理本地事物，并将本地事物处理结果返回给MQ服务
     *
     * @return COMMIT, ROLLBACK, UNKNOWN;
     */
    @Override
    public RocketMQLocalTransactionState executeLocalTransaction(Message message, Object args) {
        //将本地事物执行状态return到MQ服务，并且保存到redis备份（网络延迟，MQ服务产生回调的时候 可以从redis中获取）
        String messageId = message.getHeaders().getId().toString();
        try {
            //业务处理
            Long id = (Long) args;
            System.out.println(id);
            Goods goods = new Goods();
            goods.setId(id);
            goodsService.updateGoods(goods);
            //int i = 9 / 0;
        } catch (Exception e) {
            e.printStackTrace();
            //处理异常返回ROLLBACK
            redisTemplate.opsForValue().set(messageId, "ERROR",2, TimeUnit.HOURS);
            return RocketMQLocalTransactionState.ROLLBACK;
        }
        //处理成功返回COMMIT
        redisTemplate.opsForValue().set(messageId, "SUCCESS",2, TimeUnit.HOURS);
        return RocketMQLocalTransactionState.COMMIT;
    }


    /**
     * MQ服务 由于网络等原因 未收到 本地事物处理结果，回查本地事物处理结果
     */
    @Override
    public RocketMQLocalTransactionState checkLocalTransaction(Message message) {
        String messageId = message.getHeaders().getId().toString();
        //通过事务id获取 redis中 对应的本地事务执行状态
        String status = redisTemplate.opsForValue().
                get(messageId);
        if ("SUCCESS".equals(status)) {
            return RocketMQLocalTransactionState.COMMIT;
        } else if ("ERROR".equals(status)) {
            //继续处理，或者直接回滚
            return RocketMQLocalTransactionState.ROLLBACK;
        } else {
            return RocketMQLocalTransactionState.UNKNOWN;
        }
    }
}